﻿/**
 * Create in 2012-4-4.
 */
package kit4j.common.task.executor;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import kit4j.common.task.Task;
import kit4j.common.task.TaskState;
import kit4j.common.task.event.TaskStateChangeEvent;
import kit4j.common.task.event.TaskStateChangeListener;

/**
 * 抽象的任务执行器类型。
 * 
 * @author MiniKnife
 * 
 */
public abstract class AbstractTaskExecutor implements TaskExecutor {

	/**
	 * 任务列表。
	 */
	protected List<Task> taskList;
	
	/**
	 * 正在执行的任务集合。
	 */
	private Set<Task> runningTaskSet;

	private TaskStateChangeListener taskStateChangeListener;

	public AbstractTaskExecutor() {
		taskList = new ArrayList<Task>();
		runningTaskSet = new HashSet<Task>();
	}

	public void addTask(Task task) {
		taskList.add(task);
	}

	public void removeTask(Task task) {
		taskList.remove(task);
	}

	public void removeAllTasks() {
		taskList.clear();
	}

	public Task[] getTasks() {
		return taskList.toArray(new Task[0]);
	}

	public void start() {
		synchronized(runningTaskSet) {
			runningTaskSet.clear();
	
			for (Task task : taskList) {
				task.addTaskStateChangeListener(getTaskStateChangeListener());
				runningTaskSet.add(task);
				runTask(task);
			}
		}
	}

	private TaskStateChangeListener getTaskStateChangeListener() {
		if (taskStateChangeListener == null) {
			taskStateChangeListener = new TaskStateChangeListener() {

				@Override
				public void taskStateChanged(TaskStateChangeEvent evt) {
					Task task = evt.getTask();

					synchronized(runningTaskSet) {
						if (runningTaskSet.contains(task) && TaskState.COMPLETE.equals(evt.getNewTaskState())) {
							runningTaskSet.remove(task);
	
							task.removeTaskStateChangeListener(this);
						}
					}
				}
			};
		}

		return taskStateChangeListener;
	}

	/**
	 * 执行指定的任务。
	 * 
	 * @param task
	 *            要执行的任务对象
	 */
	abstract protected void runTask(Task task);

	/**
	 * @see kit4j.common.task.executor.TaskExecutor#pause()
	 */
	abstract public void pause();

	/**
	 * @see kit4j.common.task.executor.TaskExecutor#resume()
	 */
	abstract public void resume();

	/**
	 * @see kit4j.common.task.executor.TaskExecutor#stop()
	 */
	abstract public void stop();

	/**
	 * 重新开始当前任务序列。默认实现为使用<code>{@link #stop() stop()}</code>停止当前任务序列，然后使用<code>{@link #start() start()}</code>启动当前任务序列。
	 * 
	 * @see kit4j.common.task.executor.TaskExecutor#restart()
	 */
	public void restart() {
		stop();
		start();
	}

	/**
	 * @see kit4j.common.task.executor.TaskExecutor#waitForAllTasksComplete()
	 */
	public void waitForAllTasksComplete() {
		while (!isAllTasksComplete()) {
			Thread.yield();
		}
	}
	
	/**
	 * @return 如果当前任务序列中所有任务已经完成，则返回true，否则返回false。
	 */
	private boolean isAllTasksComplete() {
		synchronized(runningTaskSet) {
			return runningTaskSet.isEmpty();
		}
	}

}
